package org.class2table.core.util;

import cn.hutool.core.util.StrUtil;
import org.class2table.core.Class2TableException;
import org.class2table.core.dictionary.Constants;
import org.class2table.core.table.bean.ColumnMetaData;
import org.class2table.core.table.bean.TableMetaData;
import org.class2table.core.template.JavaTemplate;

import java.util.List;
import java.util.Map;
import java.util.Objects;

public class ClassBuildUtil {

    private static String buildProperty(Class<?> aClass, String columnName) {
        return String.format(
                JavaTemplate.PROPERTY_TEMPLATE,
                aClass.getName().split("[.]")[aClass.getName().split("[.]").length - 1] ,
                StrUtil.toCamelCase(columnName));
    }

    private static String buildPropertyAnnotation(ColumnMetaData columnMetaData) {
        StringBuilder propertyAnnotations = new StringBuilder();
        String columnKey = columnMetaData.getColumnKey();
        if (Constants.INFORMATION_SCHEMA.COLUMN_KEY.PRI.equals(columnKey)) {
            String primaryKeyAnnotation = String.format(JavaTemplate.PROPERTY_PRIMARY_KEY_ANNOTATION_TEMPLATE, columnMetaData.getColumnKeySort());
            propertyAnnotations.append(primaryKeyAnnotation).append(Constants.COMMON.enter);

        }
        String columnAnnotation = String.format(JavaTemplate.PROPERTY_COLUMN_ANNOTATION_TEMPLATE,
                columnMetaData.getColumnName(),
                columnMetaData.getColumnType(),
                columnMetaData.getIsNullable(),
                !Objects.isNull(columnMetaData.getColumnDefault()),
                Objects.isNull(columnMetaData.getColumnDefault()) ? Constants.COMMON.blankStr : columnMetaData.getColumnDefault(),
                columnMetaData.getColumnComment()
        );
        propertyAnnotations.append(columnAnnotation);
        return propertyAnnotations.toString();

    }

    public static String buildClass(TableMetaData tableMetaData, Map<String,Class<?>> dataType2ClazzRuleMap) {
        if (Objects.isNull(tableMetaData)) {
            return Constants.COMMON.blankStr;
        }
        StringBuilder propertyPartContent = new StringBuilder();
        List<ColumnMetaData> columnMetaDataList = tableMetaData.getEntityAttrMetaDataList();
        for (ColumnMetaData columnMetaData : columnMetaDataList) {
            String columnName = columnMetaData.getColumnName();
            String dataType = columnMetaData.getDataType();
            Class<?> aClass = dataType2ClazzRuleMap.get(dataType);
            if (Objects.isNull(aClass)) {
                throw new Class2TableException(String.format("export failed! unknown data type [%s]! please add the data type in dataType2ClazzRuleMap!", dataType));
            }
            String propertyAnnotation = buildPropertyAnnotation(columnMetaData);
            propertyPartContent.append(propertyAnnotation).append(Constants.COMMON.enter);
            String property = buildProperty(aClass, columnName);
            propertyPartContent.append(property).append(Constants.COMMON.enter2);
        }
        return String.format(JavaTemplate.CLASS_TEMPLATE, tableMetaData.getTableName(), StrUtil.upperFirst(StrUtil.toCamelCase(tableMetaData.getTableName())), propertyPartContent);
    }

}